package org.yelongframework.json.gson;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;

import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;

/**
 * 注解排除策略
 * 
 * @since 1.0.0
 */
public class AnnotationExclusionStrategy implements ExclusionStrategy {

	/** 忽略的注解 */
	private final List<Class<? extends Annotation>> ignoreAnnotations = new ArrayList<>();

	/** 只允许的注解 */
	private final List<Class<? extends Annotation>> onlyOperationAnnotations = new ArrayList<>();

	// ==================================================构造器==================================================

	public AnnotationExclusionStrategy() {
	}

	// ==================================================忽略注解==================================================

	/**
	 * @param annotationClass 忽略的注解
	 */
	public void addIgnoreAnnotation(Class<? extends Annotation> annotationClass) {
		ignoreAnnotations.add(annotationClass);
	}

	/**
	 * @param annotationClasss 忽略的注解
	 */
	public void addIgnoreAnnotations(Class<? extends Annotation>[] annotationClasss) {
		for (Class<? extends Annotation> annotationClass : annotationClasss) {
			ignoreAnnotations.add(annotationClass);
		}
	}

	/**
	 * @param annotationClasss 忽略的注解
	 */
	public void addIgnoreAnnotations(List<Class<? extends Annotation>> annotationClasss) {
		for (Class<? extends Annotation> annotationClass : annotationClasss) {
			ignoreAnnotations.add(annotationClass);
		}
	}

	/**
	 * @return 忽略的注解
	 */
	public List<Class<? extends Annotation>> getIgnoreAnnotations() {
		return ignoreAnnotations;
	}

	// ==================================================只操作注解==================================================

	/**
	 * @param annotationClass 只操作的注解
	 */
	public void addOnlyOperationAnnotation(Class<? extends Annotation> annotationClass) {
		onlyOperationAnnotations.add(annotationClass);
	}

	/**
	 * @param annotationClasss 只操作的注解
	 */
	public void addOnlyOperationAnnotations(Class<? extends Annotation>[] annotationClasss) {
		for (Class<? extends Annotation> annotationClass : annotationClasss) {
			onlyOperationAnnotations.add(annotationClass);
		}
	}

	/**
	 * @param annotationClasss 只操作的注解
	 */
	public void addOnlyOperationAnnotations(List<Class<? extends Annotation>> annotationClasss) {
		onlyOperationAnnotations.addAll(annotationClasss);
	}

	/**
	 * @return 只操作的注解
	 */
	public List<Class<? extends Annotation>> getOnlyOperationAnnotations() {
		return onlyOperationAnnotations;
	}

	// ==================================================跳过字典==================================================

	@Override
	public boolean shouldSkipField(FieldAttributes f) {
		if (!onlyOperationAnnotations.isEmpty()) {
			// 如果标注了只允许的直接则不跳过，否则跳过
			for (Class<? extends Annotation> onlyOperationAnnotation : onlyOperationAnnotations) {
				if (null != f.getAnnotation(onlyOperationAnnotation)) {
					return false;
				}
			}
			return true;
		}

		for (Class<? extends Annotation> ignoreAnnotation : ignoreAnnotations) {
			if (null != f.getAnnotation(ignoreAnnotation)) {
				return true;
			}
		}
		return false;
	}

	// ==================================================跳过类==================================================

	@Override
	public boolean shouldSkipClass(Class<?> clazz) {
		if (!onlyOperationAnnotations.isEmpty()) {
			// 如果标注了只允许的直接则不跳过，否则跳过
			for (Class<? extends Annotation> onlyOperationAnnotation : onlyOperationAnnotations) {
				if (clazz.isAnnotationPresent(onlyOperationAnnotation)) {
					return false;
				}
			}
			return true;
		}

		for (Class<? extends Annotation> ignoreAnnotation : ignoreAnnotations) {
			if (clazz.isAnnotationPresent(ignoreAnnotation)) {
				return true;
			}
		}
		return false;
	}

}
